/************************
 * 
 * @author Justin Adams 
 * Student # : 200735090
 * 
 ***********************/
package tttCore;

import java.util.ArrayList;

public class PvPManager {
	// set up private member to keep track of game play
	private Board gameBoard;
	private GameStatus currentStatus = GameStatus.IN_PROGRESS;
	private TextReader txtReader;
	private TextWriter txtWriter;
	
	public PvPManager(String input){
		String[] inputs = input.split(";");//0 is the board 1 is the row 2 is col
		txtReader = new TextReader("gameData.txt");
		txtWriter = new TextWriter("gameData.txt");
		if(input.matches("listening") || input.matches("resetFile"))
			createBoardFromString(txtReader.getLines().get(0));
		else
			createBoardFromString(inputs[0]);
	}
	
	// create the board from a string
	private void createBoardFromString(String boardString){
		gameBoard = new Board(boardString);
	}
	
	//perform the player move, but only write over the text file if 
	//client is telling the server to rewrite
	public void performPlayerMove(boolean reWrite){
		if(reWrite){
		txtWriter.writeToFile(gameBoard.printBoardAsString());
		}
		// check to see if someone has one and update the status
		checkWin();
	}
	
	// tell the text writer to write the passed in information to the file
	public void writeToFile(String stuff){
		txtWriter.writeToFile(stuff);
	}
	// get the lines of the file
	public ArrayList<String> getFileLines(){
		return txtReader.getLines();
	}
	// return the current status of the game
	public GameStatus getStatus(){
		return currentStatus;
	}
	
	// check to see if someone has won the game
	private void checkWin(){
		// test row and col wins for X and O
		for(int i=0; i<3; i++){
			testRowWin('X', i);
			testRowWin('O', i);
			testColWin('X', i);
			testColWin('O', i);
		}
		// test diagonals for X and O
		testDiagWin('X');
		testAntiDiagWin('X');
		testDiagWin('O');
		testAntiDiagWin('O');
		// test for a draw
		testDraw();
	}
	
	
	// reset the text file used for storing the current pvp board
	public void resetFile(){
		txtWriter.writeToFile("xIsNotTaken");
	}
	
	//** Private methods used to test winning conditions **/

	/** testDraw *****************************************************************
	 * 
	 * Calls the isFull method to see if the board is full, in which case currentStatus
	 * becomes draw.
	 * @pre		-	
	 * @params	- 
	 * @returns - 
	 * @post	- currentStatus is set to DRAW if the gameboard is full.
	 * ****************************************************************************/
	private void testDraw(){
		if(currentStatus == GameStatus.IN_PROGRESS)
			if(gameBoard.isFull())
				currentStatus = GameStatus.DRAW;
	}

	/** testRowWin *****************************************************************
	 * 
	 * Iterates through the rows to see if there is 3 of the same game piece in a row.
	 * Called from placePlayerPiece or aiPiece, uses the row index provided in each.
	 * @pre		-	
	 * @params	- c: Character to check for (X or O)
	 * 			  i: The row index of calling function's move
	 * @returns - 
	 * @post	- CurrentStatus is updated as X_WON or O_WON depending on the char,
	 * 			  if said event has occurred.
	 * ****************************************************************************/
	private void testRowWin(char c, int i){
		if(currentStatus == GameStatus.IN_PROGRESS)	//Only need to check if in progress. Prevents updates if win already occurred.
			for (int j = 0; j < 3; j++){	//Iterate through 3 col positions.
				if(gameBoard.get(i, j) != c)	//We're checking for a single char 3 times, 
					break;					//so if one col doesn't contain it, why continue?
				if (j == 2)	//3 in a row
					if(c == 'X')
						currentStatus = GameStatus.X_WON;
					else
						currentStatus = GameStatus.O_WON;
			}
	}

	/** testColWin *****************************************************************
	 * 
	 * Iterates through the cols to see if there is 3 of the same game piece in a col.
	 * Called from placePlayerPiece or aiPiece, uses the col index provided in each.
	 * @pre		-	
	 * @params	- c: Character to check for (X or O)
	 * 			  j: The col index of calling function's move
	 * @returns - 
	 * @post	- CurrentStatus is updated as X_WON or O_WON depending on the char,
	 * 			  if said event has occurred.
	 * ****************************************************************************/
	private void testColWin(char c, int j){
		if(currentStatus == GameStatus.IN_PROGRESS)
			for (int i = 0; i < 3; i++){
				if(gameBoard.get(i, j) != c)	//Same as testRowWin, except i is changing not j
					break;
				if (i == 2)
					if(c == 'X')
						currentStatus = GameStatus.X_WON;
					else
						currentStatus = GameStatus.O_WON;
			}
	}

	/** testDiagWin *****************************************************************
	 * 
	 * Iterates through the main diagnol (top left to bottom right) to check for 3
	 * of the same piece.
	 * 
	 * @pre		-	
	 * @params	- c: Character to check for (X or O)
	 * @returns - 
	 * @post	- CurrentStatus is updated as X_WON or O_WON depending on the char,
	 * 			  if said event has occurred.
	 * ****************************************************************************/
	private void testDiagWin(char c){
		if(currentStatus == GameStatus.IN_PROGRESS)
			for (int i = 0; i < 3; i++){
				if(gameBoard.get(i, i) != c)	//Main diag has coordinates 00, 11, 22
					break;
				if (i == 2)
					if(c == 'X')
						currentStatus = GameStatus.X_WON;
					else
						currentStatus = GameStatus.O_WON;
			}
	}

	/** testAntiDiagWin *****************************************************************
	 * 
	 * Checks the anti-diagnol (top right to bottom left) for 3 of the same char.
	 * @pre		-	
	 * @params	- c: Character to check for (X or O)
	 * @returns - 
	 * @post	- CurrentStatus is updated as X_WON or O_WON depending on the char,
	 * 			  if said event has occurred.
	 * ****************************************************************************/
	private void testAntiDiagWin(char c){
		if(currentStatus == GameStatus.IN_PROGRESS)
			for (int i = 0; i < 3; i++){
				if(gameBoard.get(i, 2-i) != c)	//Anti-diag coordinates are 02 01 00;
					break;
				if (i == 2)
					if(c == 'X')
						currentStatus = GameStatus.X_WON;
					else
						currentStatus = GameStatus.O_WON;
			}

	}

}
